﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Dycox.Windows.Forms
{
    internal class StringPropertyResolvingStrategy : IValueResolvingStrategy
    {

        public bool CanResolve(BindingConvertEventArgs bce)
        {
            return bce.DesiredType == typeof(string);
        }

        public void FormatValue(BindingConvertEventArgs bce)
        {
            
        }

        public void ParseValue(BindingConvertEventArgs bce)
        {
            string value;
            if (Convert.IsDBNull(bce.Value))
                value = null;
            else
                value = (string)bce.Value;

            if (value != null && value.Length == 0)
                bce.Value = null;
        }
    }

    internal class DateTimePickerResolvingStrategy : IValueResolvingStrategy
    {

        public bool CanResolve(BindingConvertEventArgs bce)
        {
            return
                bce.Binding.Control is DateTimePicker;
        }

        public void FormatValue(BindingConvertEventArgs bce)
        {
            object value = bce.Value;
            DateTimePicker dtp = ((DateTimePicker)bce.Binding.Control);
            if (value != null)
            {
                dtp.Checked = true;
            }
            else
            {
                dtp.Checked = false;
                // for preventing the checkbox been checked from value changing.
                bce.Value = dtp.Value;
            }
        }

        public void ParseValue(BindingConvertEventArgs bce)
        {
            if (bce.DesiredType == typeof(Nullable<DateTime>))
            {
                if (!((DateTimePicker)bce.Binding.Control).Checked)
                    bce.Value = null;
            }
        }
    }

    internal class EnumResolvingStragegy : IValueResolvingStrategy
    {
        public bool CanResolve(BindingConvertEventArgs bce)
        {
            var ctl = bce.Binding.Control;

            //return ctl is Label || ctl is TextBox || bce.DesiredType.IsEnum || bce.Value is Enum;

            return bce.DesiredType.IsEnum && bce.Value is string ||
                bce.DesiredType == typeof(string) && bce.Value is Enum;
        }

        public void FormatValue(BindingConvertEventArgs bce)
        {
            if (bce.Value is Enum && bce.DesiredType == typeof(string))
            {
                bce.Value = Dycox.EnumHelpers.GetText((Enum)bce.Value);
            }
        }

        public void ParseValue(BindingConvertEventArgs bce)
        {
            if (bce.DesiredType.IsEnum && bce.Value is string)
            {
                object v;

                if (EnumHelpers.TryParse(bce.DesiredType, (string)bce.Value, out v))
                    bce.Value = v;
            }
        }
    }

    internal class NullValueResolvingStrategy : IValueResolvingStrategy
    {
        public bool CanResolve(BindingConvertEventArgs bce)
        {
            return Convert.IsDBNull(bce.Value) && bce.DesiredType != typeof(object);
        }

        public void FormatValue(BindingConvertEventArgs bce)
        {
            if (bce.DesiredType.IsClass)
                bce.Value = null;
        }

        public void ParseValue(BindingConvertEventArgs bce)
        {
            if (bce.DesiredType.IsClass)
                bce.Value = null;
        }
    }

}

